﻿using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using Tp.GUI.Dialog;
using TpBaseObjects.Base;
using TpBaseObjects.Interfaces;
using TpBaseObjects.Objects;
using TpExtensions;
using TpTools;

namespace Tp.GUI.Controller {

    public class AbrLiefController : IController {

        #region Members

        AbrLiefControllForm myForm;
        int currentPage = 0;
        StringBuilder error = new StringBuilder();
        string liefPath = @"T:\Lief\JJ\";
        bool canGo = false;

        #endregion

        #region Constructor

        public AbrLiefController(AbrLiefControllForm form) {
            this.myForm = form;
        }

        #endregion

        #region Methods

        public void BeforeCloseMyForm(object sender, FormClosingEventArgs e) {
            if (this.myForm.MyModel.IsDirty) {
                DialogResult res = MessageBox.Show("Datensatz wurde noch nicht gespeichert. Wollen Sie jetzt speichern?", "Barverkauf", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation);
                if (res == DialogResult.Yes) {
                    //this.Save(this.myForm.MyModel);
                    return;
                }
                if (res == DialogResult.No) {
                    return;
                }
            } else {
                return;
            }
            return;
        }

        public void ChangedDetailsProperties(object sender, PropertyChangedEventArgs e) {
            if (e.PropertyName == "InUse") {
                UpdateCheckSum();
            }
        }

        public void ChangedProperties(object sender, PropertyChangedEventArgs e) {
            if (e.PropertyName == "AusgangsReNr") {
                foreach (AbrLiefRowObj rowAr in this.myForm.MyDetailsModel) {
                    rowAr.InvoiceAr = this.myForm.MyModel.AusgangsReNr;
                }
            }
            if (e.PropertyName == "EingangsReNr") {
                foreach (AbrLiefRowObj rowEr in this.myForm.MyDetailsModel) {
                    rowEr.InvoiceEr = this.myForm.MyModel.EingangsReNr;
                }
            }
        }

        public void ChangePageSelectedIndex(object sender, EventArgs e) {
            TabControl tc = sender as TabControl;
            currentPage = tc.SelectedIndex;
            canGo = false;
        }

        private bool CheckDetailsModel() {
            bool ret = true;
            error.Clear();
            int rows = 0;

            List<string> ausgangsrechnung = new List<string>();
            List<string> eingangsrechnung = new List<string>();
            foreach (AbrLiefRowObj row in this.myForm.MyDetailsModel) {
                if (row.InUse) {
                    rows += 1;
                    if (ausgangsrechnung.Count == 0) {
                        ausgangsrechnung.Add(row.InvoiceAr);
                    } else {
                        if (!ausgangsrechnung.Contains(row.InvoiceAr)) {
                            ausgangsrechnung.Add(row.InvoiceAr);
                        }
                    }
                    if (eingangsrechnung.Count == 0) {
                        eingangsrechnung.Add(row.InvoiceEr);
                    } else {
                        if (!eingangsrechnung.Contains(row.InvoiceEr)) {
                            eingangsrechnung.Add(row.InvoiceEr);
                        }
                    }
                }
            }
            if (ausgangsrechnung.Count > 1) {
                error.Append("Es wurde mehr als eine Ausgangsrechnung ausgewählt.");
            }
            if (eingangsrechnung.Count > 1) {
                error.Append("Es wurde mehr als eine Eingangsrechnung ausgewählt.");
            }
            if (rows == 0) {
                error.Append("Es wurde keine Zeile ausgewählt!");
            }
            if (error.Length > 0 || rows == 0) {
                ret = false;
            }

            return ret;
        }

        public void CloseForm(object sender, EventArgs e) {
            this.myForm.Close();
        }

        public void Dispose() {
        }

        public void LoadModels() {
            AbrLiefModelObj myModel = new AbrLiefModelObj();
            myModel.IsDirty = false;
            this.myForm.MyModel = myModel;
            this.myForm.MyModel.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(this.ChangedProperties);
            if (this.myForm.MyDetailsModel != null) {
                this.myForm.MyModel.Lieferant = this.myForm.MyDetailsModel[0].Lieferant;
                this.myForm.MyModel.AusgangsReNr = this.myForm.MyDetailsModel[0].InvoiceAr;
                this.myForm.MyModel.EingangsReNr = this.myForm.MyDetailsModel[0].InvoiceEr;
            }
            UpdateCheckSum();
        }

        public void Save(IBaseObject myObject) {
            throw new NotImplementedException("AuswahlLeistunsberichtController.Save");
        }

        private void UpdateCheckSum() {
            this.myForm.MyModel.CheckInvoiceSum = Math.Round(this.GetDetailsSummeEkVorSk(), 2);
        }

        public void Weiter(object sender, EventArgs e) {

            List<AbrLiefRowObj> details = new List<AbrLiefRowObj>();
            try {

                #region Page 0

                if (currentPage == 0) {
                    if ((Math.Round(this.myForm.MyModel.CheckInvoiceSum, 2) - Math.Round(this.myForm.MyModel.ControlSum, 2)) != 0.0) {
                        string msg = "Der eingegebene Betrag von EUR {0} stimmt nicht mit den vorhandenen Daten überein!";
                        msg = String.Format(msg, this.myForm.MyModel.ControlSum.ToString("#,##0.00"));
                        MessageBox.Show(msg, "TecOffice", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    this.myForm.MyModel.FileName = this.liefPath
                        + this.myForm.MyDetailsModel[0].BestellDatum.Date.Year.ToString().Right(2)
                        + @"\"
                        + this.myForm.MyModel.Lieferant
                        + @"\"
                        + this.myForm.MyModel.Lieferant
                        + this.myForm.MyDetailsModel[0].BestellDatum.Date.Year.ToString().Right(2)
                        + ".xlsx";

                    this.myForm.MyModel.Sheetname = "Su";

                    if (this.myForm.MyModel.Lieferant == "Hm") {
                        if (this.myForm.MyDetailsModel[0].InvoiceEr.Right(2) == "Lc"
                            || this.myForm.MyDetailsModel[0].InvoiceEr.Right(2) == "Gt") {
                            this.myForm.MyModel.Sheetname += this.myForm.MyDetailsModel[0].InvoiceEr.Right(2);
                        }
                    }

                    if (!CheckDetailsModel()) {
                        MessageBox.Show(error.ToString(), "TecOffice", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    currentPage = 1;
                    this.myForm.ShowTabControl(currentPage);
                    canGo = true;
                    return;
                }

                #endregion

                #region Page 1

                if (currentPage == 1) {
                    if (!canGo) {
                        this.myForm.ShowTabControl(0);
                        return;
                    }

                    foreach (AbrLiefRowObj row in this.myForm.MyDetailsModel) {
                        if (row.InUse) {
                            details.Add(row);
                        }
                    }

                    this.myForm.Cancel = false;
                    WriteModelToFile(details, this.myForm.MyModel);
                    if (!this.myForm.Cancel) {
                        this.myForm.DetailsForMarkup = details;
                        this.myForm.Close();
                    }
                    
                }

                #endregion

            } catch (Exception ex) {
                this.myForm.Cancel = true;
                MessageBox.Show("Fehler : " + ex.Message, "TecOffice", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void WriteModelToFile(List<AbrLiefRowObj> detailsModel, AbrLiefModelObj model) {
            string fileName = model.FileName;
            Workbook wb = null;
            if (!Office.CheckExcelFile(fileName)) {
                return;
            }
            try {
                Microsoft.Office.Interop.Excel.Application exApp = Office.GetExcelApplication();
                wb = exApp.Workbooks.Open(fileName);
                string sheetName = this.myForm.MyModel.Sheetname;

                if (!Tools.SheetsExists(wb, sheetName)) {
                    MessageBox.Show("Das Register " + sheetName + " ist nicht vorhanden.", "TecOffice", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    wb.Close();
                    return;
                }
                Worksheet sh = wb.Sheets[sheetName];

                int startRow = 2;
                bool weiter = true;
                List<ProjectRow> lfList = new List<ProjectRow>();

                while (weiter && startRow < 5000) {
                    Range su = sh.Cells[startRow, "C"];
                    Range year = sh.Cells[startRow, "D"];

                    if (su.Value != null) {
                        if (su.Value.ToString().Contains("Summe")) {
                            if (year.Value != null) {
                                if (Convert.ToInt32(year.Value) == detailsModel[0].BestellDatum.Year) {
                                    break;
                                }
                            }
                        }
                    }


                    Range row = sh.Rows[startRow, Missing.Value];
                    ProjectRow lfRow = new ProjectRow(row);
                    if (lfRow.BestellNr == detailsModel[0].BestellNummer) {
                        lfList.Add(lfRow);
                    }
                    startRow++;
                }

                int i = 0;
                if (lfList.Count == detailsModel.Count) {
                    foreach (ProjectRow mRow in lfList) {
                        mRow.Auftragsnummer = detailsModel[i].AuftragNummer;
                        mRow.Bestelldatum = detailsModel[i].BestellDatum;
                        mRow.BestellNr = detailsModel[i].BestellNummer;
                        mRow.Einheit = detailsModel[i].Einheit;
                        mRow.Einzelpreis = detailsModel[i].EinzelPreis;
                        mRow.EkVorSk = detailsModel[i].EkVorSK;
                        mRow.AusgangsrechnungsNr = detailsModel[i].InvoiceAr;
                        mRow.EingangsrechnungsNr = detailsModel[i].InvoiceEr;
                        mRow.KundenName = detailsModel[i].Kunde;
                        mRow.Menge = detailsModel[i].Menge;
                        mRow.Leistung = detailsModel[i].Produkt;
                        mRow.ProjectName = detailsModel[i].Project;
                        mRow.SummeEp = detailsModel[i].SummePreis;
                        mRow.Lieferant = detailsModel[i].Lieferant;
                        mRow.MyRow.Font.Bold = false;
                        mRow.MyRow.EntireRow.Hidden = true;
                        i++;
                    }
                }

                ((Microsoft.Office.Interop.Excel._Worksheet)sh).Activate();
                if (lfList.Count != detailsModel.Count) {
                    foreach (ProjectRow dRow in lfList) {
                        Range delRow = sh.Rows[dRow.CurrentRowNumber, Missing.Value];
                        delRow.Delete(Shift: XlDeleteShiftDirection.xlShiftUp);
                    }

                    startRow = 2;
                    weiter = true;
                    Range sr1;
                    Range sr2;
                    ProjectRow curRow;
                    ProjectRow nextRow;
                    
                    while (weiter && startRow < 5000) {
                        sr1 = sh.Rows[startRow, Missing.Value];
                        sr2 = sh.Rows[startRow + 1, Missing.Value];

                        curRow = new ProjectRow(sr1);
                        nextRow = new ProjectRow(sr2);

                        if ((curRow.Auftragsnummer < detailsModel[0].AuftragNummer
                            && nextRow.Auftragsnummer > detailsModel[0].AuftragNummer)
                            || (detailsModel[0].AuftragNummer == 1 && nextRow.Auftragsnummer != 1)) {

                                if (detailsModel[0].AuftragNummer != 1) {
                                    startRow++;
                                    sr1 = sh.Rows[startRow, Missing.Value];
                                }

                            foreach (AbrLiefRowObj lfRow in detailsModel) {
                                sr1.Select();
                                sr1.Copy();
                                sr1.Insert(Shift: XlInsertShiftDirection.xlShiftDown);

                                sr2 = sh.Rows[startRow, Missing.Value];
                                ProjectRow inRow = new ProjectRow(sr2);

                                inRow.Auftragsnummer = lfRow.AuftragNummer;
                                inRow.Bestelldatum = lfRow.BestellDatum;
                                inRow.BestellNr = lfRow.BestellNummer;
                                inRow.Einheit = lfRow.Einheit;
                                inRow.Einzelpreis = lfRow.EinzelPreis;
                                inRow.EkVorSk = lfRow.EkVorSK;
                                inRow.AusgangsrechnungsNr = lfRow.InvoiceAr;
                                inRow.EingangsrechnungsNr = lfRow.InvoiceEr;
                                inRow.KundenName = lfRow.Kunde;
                                inRow.Menge = lfRow.Menge;
                                inRow.Leistung = lfRow.Produkt;
                                inRow.ProjectName = lfRow.Project;
                                inRow.SummeEp = lfRow.SummePreis;
                                inRow.Lieferant = lfRow.Lieferant;
                                inRow.MyRow.Font.Bold = false;
                                inRow.MyRow.EntireRow.Hidden = true;

                                startRow++;
                                sr1 = sh.Rows[startRow, Missing.Value];

                            }
                            return;
                        }
                        startRow++;
                    }
                }
            } catch (Exception ex) {
                this.myForm.Cancel = true;
                MessageBox.Show("Fehler : " + ex.Message, "TecOffice", MessageBoxButtons.OK, MessageBoxIcon.Error);
            } finally {
                if (wb != null) {
                    wb.Save();
                    wb.Close();
                }
            }

        }

        #endregion

        #region Functions

        public double GetDetailsSummeEkVorSk() {
            double ret = 0.0;
            foreach (AbrLiefRowObj row in this.myForm.MyDetailsModel) {
                if (row.InUse) {
                    ret += row.EkVorSK;
                }
            }
            return ret;
        }

        #endregion

    }
}
